from datetime import datetime, timedelta
from jose import jwt, JWTError
from backend.config.config import settings
from fastapi import Depends, HTTPException, status, Header
from typing import Optional, List
from backend.models.user import User
from backend.schemas.user import TokenData
from backend.services.user_service import UserService

# 使用settings中的配置
SECRET_KEY = settings.SECRET_KEY if hasattr(settings, "SECRET_KEY") else "your_secret_key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = settings.ACCESS_TOKEN_EXPIRE_MINUTES if hasattr(settings, "ACCESS_TOKEN_EXPIRE_MINUTES") else 60 * 24


async def create_access_token(user: User):
    """创建JWT访问令牌"""
    permissions = await UserService.get_user_permissions(user)
    
    data = {
        "sub": user.username,
        "permissions": list(permissions),
        "user_id": user.id
    }
    
    expires_delta = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    expire = datetime.utcnow() + expires_delta
    data.update({"exp": expire})
    
    encoded_jwt = jwt.encode(data, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt


def verify_token(token: str):
    """验证JWT令牌"""
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        return payload
    except JWTError:
        return None


def get_token_from_header(authorization: Optional[str] = Header(None)):
    """从Authorization header中提取JWT token"""
    if not authorization:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="缺少Authorization header",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    try:
        scheme, token = authorization.split()
        if scheme.lower() != "bearer":
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="无效的认证方案，请使用Bearer token",
                headers={"WWW-Authenticate": "Bearer"},
            )
        return token
    except ValueError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="无效的Authorization header格式",
            headers={"WWW-Authenticate": "Bearer"},
        )


async def get_current_user(authorization: Optional[str] = Header(None)):
    """获取当前用户（通过JWT认证）"""
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="无效的身份验证凭据",
        headers={"WWW-Authenticate": "Bearer"},
    )
    
    # 从header中获取token
    token = get_token_from_header(authorization)
    
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
        permissions: List[str] = payload.get("permissions", [])
        token_data = TokenData(username=username, permissions=permissions)
    except JWTError:
        raise credentials_exception
    
    user = await User.get_or_none(username=token_data.username).prefetch_related("roles__permissions")
    if user is None:
        raise credentials_exception
    return user


async def get_current_active_user(authorization: Optional[str] = Header(None)):
    """获取当前活跃用户"""
    current_user = await get_current_user(authorization)
    if not current_user.is_active:
        raise HTTPException(status_code=400, detail="用户已禁用")
    return current_user


async def get_current_admin_user(authorization: Optional[str] = Header(None)):
    """获取当前管理员用户"""
    current_user = await get_current_active_user(authorization)
    is_admin = False
    
    # Check if user is superuser
    if current_user.is_superuser:
        is_admin = True
    else:
        # Check roles for admin role
        await current_user.fetch_related("roles")
        for role in current_user.roles:
            if role.code == "admin":
                is_admin = True
                break
    
    if not is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="没有足够的权限执行此操作",
        )
    return current_user


def require_permissions(required_permissions: List[str]):
    """
    创建一个依赖项，检查当前用户是否拥有所需的权限
    """
    async def permission_checker(authorization: Optional[str] = Header(None)):
        current_user = await get_current_active_user(authorization)
        
        # Superusers have all permissions
        if current_user.is_superuser:
            return current_user
            
        # Get user permissions
        user_permissions = await UserService.get_user_permissions(current_user)
        
        # Check if user has all required permissions
        for permission in required_permissions:
            if permission not in user_permissions:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail=f"权限不足，需要权限: {permission}"
                )
        
        return current_user
        
    return permission_checker